package com.kinsin.kinsinutil

import android.app.Activity
import android.content.Context
import android.graphics.Rect
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.EditText

object KeyboardUtils {

    /**
     * 显示软键盘
     * @param view 需要接收输入的视图（如 EditText）
     * @param delay 延迟显示时间（毫秒），默认立即显示
     *
     * ### 常见问题：点击按钮后直接弹出软键盘
     * **问**：我想点击按钮后就弹出软键盘，而不是在输入框之后弹出？
     * **答**：不能直接使用Button显示软键盘，但可以通过间接方式实现。以下是原理说明和改造方案：
     *
     * ### 实现方案
     * **核心原理**
     * 系统限制：Android 要求软键盘必须关联到可输入视图（如 EditText）
     * 焦点机制：只有获得焦点的输入视图才能触发键盘显示
     *
     * **InputMethodManager 工作逻辑**（系统源码节选）：
     * ```java
     * if (view.isFocusable && view.isFocusableInTouchMode && view.isFocused()) {
     *     showSoftInput(...) // 真正显示键盘
     * }
     * ```
     *
     * ### 改造方案
     * **流程**：`[点击 Button] → [将焦点转移到隐藏的 EditText] → [显示键盘]`
     *
     * 1. 布局中添加透明输入视图：
     * ```xml
     * <EditText
     *     android:id="@+id/hidden_edit"
     *     android:layout_width="0dp"
     *     android:layout_height="0dp"
     *     android:background="@null"
     *     android:inputType="text"/>
     * ```
     *
     * 2. Button 点击处理：
     * ```kotlin
     * button.setOnClickListener {
     *     hidden_edit.requestFocus()
     *     hidden_edit.showKeyboard()
     * }
     * ```
     */
    fun showKeyboard(view: View, delay: Long = 0) {
        view.postDelayed({
            val inputManager = view.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
            view.requestFocus()
            inputManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT)
        }, delay)
    }

    /**
     * 隐藏软键盘
     * @param activity 当前Activity实例
     */
    fun hideKeyboard(activity: Activity) {
        val inputManager = activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        val currentFocus = activity.currentFocus
        currentFocus?.let {
            inputManager.hideSoftInputFromWindow(
                it.windowToken,
                InputMethodManager.HIDE_NOT_ALWAYS
            )
        } ?: run {
            // 如果当前没有焦点视图，使用顶层窗口的Token
            activity.window.decorView.rootView.apply {
                inputManager.hideSoftInputFromWindow(windowToken, 0)
            }
        }
    }

    /**
     * 检测软键盘是否可见
     * @param activity 当前Activity实例
     * @param threshold 判定阈值（单位：像素），默认200px
     */
    fun isKeyboardVisible(activity: Activity, threshold: Int = 200): Boolean {
        val decorView = activity.window.decorView
        val rect = Rect().apply {
            decorView.getWindowVisibleDisplayFrame(this)
        }
        // 计算键盘可能的高度
        val keypadHeight = decorView.rootView.height - rect.bottom
        return keypadHeight > threshold
    }

    /* 扩展函数 */
    
    // Activity扩展：隐藏键盘
    @JvmName("hideKeyboardKtxActivity")
    fun Activity.hideKeyboard() = KeyboardUtils.hideKeyboard(this)

    // View扩展：隐藏键盘
    @JvmName("hideKeyboardKtxView")
    fun View.hideKeyboard() {
        val inputManager = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        inputManager.hideSoftInputFromWindow(windowToken, 0)
    }

    // EditText扩展：显示键盘
    @JvmName("showKeyboardKtxEditText")
    fun EditText.showKeyboard(delay: Long = 0) = KeyboardUtils.showKeyboard(this, delay)

    // Activity扩展：检查键盘状态
    @JvmName("isKeyboardVisibleKtxActivity")
    fun Activity.isKeyboardVisible(threshold: Int = 200) =
        KeyboardUtils.isKeyboardVisible(this, threshold)
}